package cn.iocoder.yudao.module.hs.framework.core.aop;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.hs.dal.dataobject.materiallog.MaterialLogDO;
import cn.iocoder.yudao.module.hs.framework.core.annotations.MaterialLog;
import cn.iocoder.yudao.module.hs.service.materiallog.MaterialLogService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
import static java.util.Collections.emptyMap;

/**
 * 物料的操作日志的记录 AOP 切面
 */
@Component
@Aspect
@Slf4j
public class MaterialLogAspect {

    /**
     * 物料编号
     */
    private static final ThreadLocal<List<Long>> MATERIAL_ID = new ThreadLocal<>();
    /**
     * 拓展参数 Map，用于格式化操作内容
     */
    private static final ThreadLocal<Map<String, Object>> EXPANSION = new ThreadLocal<>();

    @Resource
    private MaterialLogService materialLogService;

    @AfterReturning("@annotation(materialLog)")
    public void doAfterReturning(MaterialLog materialLog) {
        try {
            // 操作用户
            Long userId = getUserId();
            // 物料信息
            List<Long> materialIds = MATERIAL_ID.get();
            // 如果未设置，只有注解，说明不需要记录日志
            if (CollectionUtil.isEmpty(materialIds)) {
                return;
            }
            Map<String, Object> expansion = ObjectUtil.defaultIfNull(EXPANSION.get(), emptyMap());
            String content = StrUtil.format(materialLog.operateType().getContent(), expansion);
            materialLogService.batchCreateMaterialLog(userId, materialLog.operateType().getType(), materialIds, content);
        } catch (Exception ex) {
            log.error("[doAfterReturning][orderLog({}) 订单日志错误]", toJsonString(materialLog), ex);
        } finally {
            clear();
        }
    }

    /**
     * 获得用户编号
     * <p>
     * 如果没有，则约定为 {@link MaterialLogDO#getUserId()} 系统
     *
     * @return 用户类型
     */
    private static Long getUserId() {
        return ObjectUtil.defaultIfNull(WebFrameworkUtils.getLoginUserId(), MaterialLogDO.USER_ID_SYSTEM);
    }

    public static void setMaterialInfo(List<Long> ids, Map<String, Object> expansion) {
        MATERIAL_ID.set(ids);
        EXPANSION.set(expansion);
    }


    private static void clear() {
        MATERIAL_ID.remove();
        EXPANSION.remove();
    }

}
